📞 叢集內的Pod因應需求,需要對外或對內提供通訊及訪問入口,像是要給客戶使用或是前端pod需連到後端pod(一群),K8s提供Service
object,如此一來就不用為了使用其他service discovery機制,去修改程式,另外,K8s設計概念中Pod的變動性高,Deployment確保服務運作,Pod雖然各自擁有IP,不過每次新生成Pod,就會換個IP,那下次連線又要修改IP,實務上實在是讓人難以管控,以上種種問題,找Service
處理吧~
Service將這些通訊抽象化,有自己的ip,定義端點(endpoints)的邏輯及存取政策,讓Pod可以透過網路被訪問,這種抽象化,也解開耦合連線的關係,交由Service處理與追蹤,建立時同步建立DNS entry,類型分3種:
ClusterIP(預設): 服務透過叢集內的virtual IP對外開放,service之間互相溝通
NodePort: 同cluterIP建立cluster ip位址,服務藉由node ip的靜態port對外開放,映射NodePort和Pod的Port,「cluster內」連線用(跨越node),使用selector選取pod(label)
LoadBalancer: 外部的service機制,特定cloud provider支持此設定(gcp, aws, azure…)
DNS
連線時,透過DNS較IP更加方便,提升可讀性,並且免於IP浮動而需重設定的情況,大致的規則如下:
hostname | namespace | type(subdomain) | root(預設K8s domain) | ip address |
---|---|---|---|---|
service的名稱 | ooo | svc | cluster.local | xxx.xxx.xx.xx |
假設cluster內有個service名稱為my-service, namespace位於john-doe,IP為10.107.30.100,連線時:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort # 指定類型, 預設為ClusterIP
selector: # 標定要怎麼抓Pod
app.kubernetes.io/name: MyApp
ports:
- port: 80 # 預設目標port的port和service port相同
targetPort: 80
nodePort: 30007
Service 操作指令
# Service的ip range預設為10.0.0.0/24
取得service 資訊
kubectl get service
kubectl get svc
kubectl describe service <名稱>
# 建立service
# 直接指定要建立service的pod, 自動使用pod的label作為selector, type預設為ClusterIP
kubectl expose pod <pod名稱> --port=<xx> --target-port=<xx> --type=ClusterIP --name=httpd
or
kubectl run httpd --image=httpd:alpine --port=80 --expose
# 建立指令類型的service, type=clusterip, nodeport, loadbalancer
# 無法指定selector, 預設label為app:<service名稱>
# 若要指定, 可以先匯出檔案修改設定, 加上 --dry-run=client -o yaml
kubectl create service clusterip <名稱> --tcp=<port>:<targetPort>
kubectl create service nodeport <名稱> --tcp=<port>:<targetPort>
附註:
大部分的Object,需符合DNS subdomain名稱規則,也就是
REF. Object Names and IDs